#include <Arduino.h>
#include <WiFi.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <FastLED.h>
#include <DHT.h>
#include <Wire.h>
#include <BH1750.h>
#include <SoftwareSerial.h>
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <AliyunIoTSDK.h>
#include <esp_task_wdt.h>
#include "demos\lv_demos.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

// 包含LVGL生成的UI头文件
#include "../libraries/lvgl/src/generated/gui_guider.h"
#include "../libraries/lvgl/src/generated/events_init.h"

// 硬件配置
#define PRODUCT_KEY "k29s1SowyFa"
#define DEVICE_NAME "Muelsyse"
#define DEVICE_SECRET "1cb53cecb29885b370fce4aeb1a7931c"
#define REGION_ID "cn-shanghai"

// 引脚定义
#define TX_PIN 41
#define RX_PIN 42
#define LED_PIN 12
#define NUM_LEDS 10
#define DHTPIN 7
#define DHTTYPE DHT11
#define WATERPIN 4

// FreeRTOS配置
enum TaskPriority {
  TASK_LVGL_PRIO = 2,
  TASK_NET_PRIO = 1,
  TASK_SENSOR_PRIO = 1,
  TASK_SERIAL_PRIO = 2,
  TASK_SAFE_PRIO = 2
};

// 全局对象
lv_ui guider_ui;
BH1750 lightMeter;
CRGB leds[NUM_LEDS];
DHT dht(DHTPIN, DHTTYPE);
TFT_eSPI tft = TFT_eSPI(160, 128);
WiFiClient espClient;

// 定义传感器数据结构
typedef struct {
  float temperature;
  float humidity;
} SensorData;

typedef struct {
    char data[128];
} QueueElement;

// 创建队列
QueueHandle_t sensorDataQueue;

// 共享资源
SemaphoreHandle_t i2cMutex;
QueueHandle_t cmdQueue;

// LVGL配置
static const uint16_t screenWidth = 160;
static const uint16_t screenHeight = 128;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * screenHeight];

TaskHandle_t lvglTaskHandle;
TaskHandle_t networkTaskHandle;
TaskHandle_t sensorTaskHandle;
TaskHandle_t serialTaskHandle;
TaskHandle_t safetyTaskHandle;

// 函数声明
void initHardware();
void lvglTask(void *pv);
void networkTask(void *pv);
void sensorTask(void *pv);
void serialTask(void *pv);
void safetyTask(void *pv);
void wifiInit(const char *ssid, const char *passphrase);
//void updateDisplay(float temp, float humi);
void processQueueCommands();
void sendSensorData();
void checkSystemHealth();
void panicHandler(const char *msg);

char *ssid = "伊蕾娜小姐我喜欢你啊";
char *password = "wsnbb123";

void setup() {

  // 初始化硬件
  initHardware();

  // // 看门狗配置
  // esp_task_wdt_config_t wdt_config = {
  //   .timeout_ms = 35000,
  //   .idle_core_mask = 0, // 监控两个核心
  //   .trigger_panic = false
  // };
  // esp_task_wdt_init(&wdt_config);

  Serial.printf("Hardware init OK\n");
  // 创建RTOS资源
  i2cMutex = xSemaphoreCreateMutex();
  cmdQueue = xQueueCreate(5, sizeof(QueueElement));
  sensorDataQueue = xQueueCreate(6, sizeof(SensorData));
  Serial.printf("Ready to freertos\n");
  // 在setup()中添加内存监控
  Serial.printf("初始化后内存状态:\n");
  Serial.printf(" - 内部RAM: %dKB\n", esp_get_free_internal_heap_size() / 1024);
  Serial.printf(" - 内部heap: %dKB\n", ESP.getFreeHeap() / 1024);
  // 创建任务
  xTaskCreate(lvglTask, "LVGL", 1024 * 8, NULL, TASK_LVGL_PRIO, &lvglTaskHandle);
  // esp_task_wdt_add(lvglTaskHandle);
  xTaskCreate(networkTask, "NET", 1024 * 8, NULL, TASK_NET_PRIO, &networkTaskHandle);
  // esp_task_wdt_add(networkTaskHandle);
  xTaskCreate(sensorTask, "SENSOR", 1024 * 4, NULL, TASK_SENSOR_PRIO, &sensorTaskHandle);
  // esp_task_wdt_add(sensorTaskHandle);
  xTaskCreate(serialTask, "SERIAL", 1024 * 4, NULL, TASK_SERIAL_PRIO, &serialTaskHandle);
  // Serial.printf("serTask created\n");
  // esp_task_wdt_add(serialTaskHandle);
  xTaskCreate(safetyTask, "SAFETY", 1024 * 4, NULL, TASK_SAFE_PRIO, &safetyTaskHandle);
  // esp_task_wdt_add(safetyTaskHandle);
}

void loop() {
}

// 硬件初始化
void initHardware() {
  Serial.begin(115200);
  Serial.printf("Serial init OK\n");
  // 网络初始化
  wifiInit(ssid, password);
  tft.begin();
  tft.setRotation(3);

  Serial.printf("LVGL init OK\n");

  // 外设初始化            // start here
  Wire.begin(17, 18);
  pinMode(WATERPIN, OUTPUT);
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
  Serial.printf("dht init OK\n");
  AliyunIoTSDK::begin(espClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);
  delay(1000);
  Serial.printf("Hardware init OK\n");
}

// FreeRTOS任务函数
void lvglTask(void *pv) {
  const TickType_t interval = pdMS_TO_TICKS(10);
  // tft.initDMA();
  Serial.printf("lvglTask init OK\n");
  // LVGL初始化
  //lvglBuf = (lv_color_t*)ps_malloc(screenWidth*screenHeight*sizeof(lv_color_t));
  //lvglBuf = (lv_color_t*)ps_calloc(screenWidth * screenHeight, sizeof(lv_color_t));
  lv_init();
  lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * screenHeight);

  lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  setup_ui(&guider_ui);
  events_init(&guider_ui);

  lv_obj_t *temp_bar = guider_ui.screen_bar_2;
  lv_obj_t *humi_bar = guider_ui.screen_bar_1;

  while (1) {
    lv_timer_handler();
    // 检查队列是否有新数据
    SensorData data;
    if (xQueueReceive(sensorDataQueue, &data, 0) == pdTRUE) {
      // 更新温度Bar（假设温度范围0-50°C）
      lv_bar_set_range(temp_bar, 0, 50);
      lv_bar_set_value(temp_bar, data.temperature, LV_ANIM_OFF);

      // 更新湿度Bar（假设湿度范围0-100）
      lv_bar_set_range(humi_bar, 0, 100);
      lv_bar_set_value(humi_bar, data.humidity, LV_ANIM_OFF);
    }
    vTaskDelay(interval);
    // esp_task_wdt_reset();
    // 监控堆栈使用
    UBaseType_t watermark = uxTaskGetStackHighWaterMark(NULL);
    if (watermark < 1024) {  // 剩余堆栈不足1KB时报警
      Serial.printf("[警告] LVGL任务堆栈剩余: %d字节\n", watermark * 4);
    }
  }
}

void networkTask(void *pv) {
  const TickType_t interval = pdMS_TO_TICKS(10000);
  Serial.printf("netTask init OK\n");
  while (1) {
    AliyunIoTSDK::loop();
    sendSensorData();
    vTaskDelay(interval);
    // esp_task_wdt_reset();
  }
}

void sensorTask(void *pv) {
  const TickType_t interval = pdMS_TO_TICKS(5000);
  Serial.printf("SensorTask init OK\n");
  if (!lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
    panicHandler("BH1750 Init Fail");
  }

  dht.begin();
  while (1) {
    float temp = dht.readTemperature();
    float humi = analogRead(A0) / 100.0f;
    if (xSemaphoreTake(i2cMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
      uint16_t lux = lightMeter.readLightLevel();
      xSemaphoreGive(i2cMutex);
    }
    //updateDisplay(temp, humi);
    // esp_task_wdt_reset();
    // 将数据打包并发送到队列
    SensorData data = { temp, humi };
    xQueueSend(sensorDataQueue, &data, portMAX_DELAY);
    vTaskDelay(interval);
  }
}

void serialTask(void *pv) {
  Serial.printf("serialTask init OK\n");
  SoftwareSerial mySerial(RX_PIN, TX_PIN);
  mySerial.begin(9600);
  while (1) {
    if (mySerial.available() > 0) {
      QueueElement elem;
      size_t len = mySerial.readBytesUntil('\n', elem.data, sizeof(elem.data) - 1);
      elem.data[len] = '\0';  // 确保字符串以\0结尾

      xQueueSend(cmdQueue, &elem, portMAX_DELAY);
    }
    processQueueCommands();
    vTaskDelay(pdMS_TO_TICKS(100));
    // esp_task_wdt_reset();
  }
}

void safetyTask(void *pv) {
  Serial.printf("safeTask init OK\n");
  const TickType_t interval = pdMS_TO_TICKS(30);
  while (1) {
    checkSystemHealth();
    vTaskDelay(interval);
    // esp_task_wdt_reset();
  }
}

// 功能函数
void wifiInit(const char *ssid, const char *passphrase) {
  WiFi.begin(ssid, passphrase);
  for (int i = 0; i < 100; i++) {  // 增加循环次数至40（20秒）
    wl_status_t status = WiFi.status();
    Serial.printf("%d\n", status);  // 输出具体状态码
    if (status == WL_CONNECTED) {
      Serial.println("\nWiFi已连接");
      Serial.print("IP地址: ");
      Serial.println(WiFi.localIP());  // 确认IP是否有效
      return;
    }
    delay(500);
    Serial.print(".");
  }
  panicHandler("WiFi连接失败");
}

// void updateDisplay(float temp, float humi) {
//   lv_label_set_text_fmt(guider_ui.screen_label_temp, "%.1f°C", temp);
//   lv_label_set_text_fmt(guider_ui.screen_label_humi, "%.1f%%", humi);
// }

void processQueueCommands() {
  QueueElement elem;
  while (xQueueReceive(cmdQueue, &elem, 0) == pdTRUE) {
    char* cmdStr = elem.data;
    Serial.printf("serialReceived: %s\n", cmdStr);
    if (strstr(cmdStr, "灯")) {
      if (strstr(cmdStr, "开")) {
        fill_solid(leds, NUM_LEDS, CRGB(255, 200, 20));
        FastLED.show();
        AliyunIoTSDK::send("LightLuminance", 1);
      } else if (strstr(cmdStr, "关")) {
        fill_solid(leds, NUM_LEDS, CRGB::Black);
        FastLED.show();
        AliyunIoTSDK::send("LightLuminance", 0);
      }
    } else if (strstr(cmdStr, "水")) {
      if (strstr(cmdStr, "开")) {
        digitalWrite(WATERPIN, HIGH);
        AliyunIoTSDK::send("IrrigationPumpStatus", 1);
      } else if (strstr(cmdStr, "关")) {
        digitalWrite(WATERPIN, LOW);
        AliyunIoTSDK::send("IrrigationPumpStatus", 0);
      }
    }
    memset(elem.data, 0, sizeof(elem.data));  // 清空缓冲区
  }
}

void sendSensorData() {
  float temp, humi;
  uint16_t lux;

  if (xSemaphoreTake(i2cMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
    temp = dht.readTemperature();
    humi = analogRead(A0) / 100.0f;
    lux = lightMeter.readLightLevel();

    AliyunIoTSDK::send("CurrentTemperature", temp);
    AliyunIoTSDK::send("CurrentHumidity", humi);
    AliyunIoTSDK::send("LightLux", lux);
    xSemaphoreGive(i2cMutex);
  }
  Serial.printf(" - 内部RAM: %dKB\n", esp_get_free_internal_heap_size() / 1024);
  Serial.printf(" - 内部heap: %dKB\n", ESP.getFreeHeap() / 1024);
}

void checkSystemHealth() {
  // Serial.printf("[系统健康] 内存: 内部=%dB, PSRAM=%dB\n",
  //               heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
  //               heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  // if (WiFi.status() != WL_CONNECTED) {
  //   WiFi.reconnect();
  //   vTaskDelay(pdMS_TO_TICKS(5000));
  //   if (WiFi.status() != WL_CONNECTED) ESP.restart();
  // }
}

void panicHandler(const char *msg) {
  Serial.printf("[严重错误] %s\n", msg);
  while (1) {
    delay(200);
  }
}

// LVGL显示刷新函数
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint32_t w = area->x2 - area->x1 + 1;
  uint32_t h = area->y2 - area->y1 + 1;

  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t *)&color_p->full, w * h, true);
  tft.endWrite();

  lv_disp_flush_ready(disp);
}
